package tum0r.webengine.extension

import com.alibaba.fastjson.JSON

/**
 * 说明: 有关类型的操作，包含Java Class和Kotlin Class
 *
 * 创建者: tum0r
 *
 * 时间: 2021/8/19 19:33
 */

/**
 * 类是否是基础类型（包含String类型）
 */
fun Class<*>.isPrimitiveType(): Boolean {
    val name = this.canonicalName
    return this.isPrimitive || name.equals("java.lang.Boolean") || name.equals("java.lang.Byte") || name.equals("java.lang.Short") || name.equals("java.lang.Integer") || name.equals("java.lang.Long") ||
            name.equals("java.lang.Character") || name.equals("java.lang.Float") || name.equals("java.lang.Double") || name.equals("java.lang.String")
}

/**
 * 将值转换为本类的数据
 *
 * @param[value] 要被转换的值
 */
fun Class<*>.convert(value: Any?): Any? {
    if (value != null) {
        return if (this == value::class.java) value
        else {
            when (this) {
                String::class.java -> value.toString()
                else -> try {
                    JSON.parseObject(value.toString(), this)
                } catch (e: Exception) {
                    null
                }
            }
        }
    } else
        return when (this.canonicalName) {
            "boolean", "java.lang.Boolean" -> false
            "byte", "java.lang.Byte" -> "0".toByte()
            "short", "java.lang.Short" -> "0".toShort()
            "int", "java.lang.Integer", "char", "java.lang.Character" -> '0'
            "long", "java.lang.Long" -> 0L
            "float", "java.lang.Float" -> 0
            "double", "java.lang.Double" -> 0
            "java.lang.String" -> ""
            else -> null
        }
}

/**
 * 将值转换为指定类的数据
 *
 * @param[values] 要被转换的值数组
 *
 * @return 以类数组长度为准，多出的值不会转换，缺少的值返回null
 */
fun Array<Class<*>>.convert(values: Array<Any?>): Array<Any?> {
    val result = Array<Any?>(this.size) { null }
    for (i in 0 until this.size) result[i] = this[i].convert(if (i < values.size) values[i] else null)
    return result
}

/**
 * 将值转换为指定类的数据
 *
 * @param[values] 要被转换的值集合
 *
 * @return 以类集合长度为准，多出的值不会转换，缺少的值返回null
 */
fun ArrayList<Class<*>>.convert(values: ArrayList<Any?>): ArrayList<Any?> {
    val result = ArrayList<Any?>(this.size)
    for (i in 0 until this.size) result[i] = this[i].convert(if (i < values.size) values[i] else null)
    return result
}